package com.zombies.list.arraylist;

import com.zombies.list.adt.MyList;




/**
 * 线性表的顺序存储结构(数组)实现
 * @date 2022-04-09 09:49:27
 *  1、定长数组
 *  2、没有实现自动扩展功能，后期可以实现
 *
 * @author zombies
 * @create 2022-04-09 9:43
 */
public class MyArrayList<E> implements MyList<E> {

    private Object[] objects = null;

    /**
     * 线性表实际存在元素的长度
     *
     */
    private int size = 0;


    /**
     * 空参构造方法
     *
     */
    public MyArrayList() {

        objects = new Object[1024];
    }

    /**
     * 确定线性表的长度
     *
     */
    public MyArrayList(int listLength){
        //listLength安全性判断
        if(listLength < 0){
            throw new IllegalArgumentException("线性表长度需要大于0");
        }
        objects = new Object[listLength];
    }


    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public boolean isFull() {
        return size == objects.length;
    }

    @Override
    public E getFirst() {
        if(!isEmpty()){
            return (E)objects[0];
        }
        return null;
    }

    @Override
    public E getLast() {
        if(!isEmpty()){
            return (E)objects[size - 1];
        }
        return null;
    }

    //这个顺序存储结构的线性表在移除第一个元素后,后面的元素都要往前移动
    @Override
    public E removeFirst() {
        if(!isEmpty()){
            E temp = (E)objects[0];

            // 0 <= i <= size - 1 - 1
            for (int i = 0; i < size - 1; i++) {
                objects[i] = objects[i + 1];
            }
            size--;
            return temp;
        }
        return null;
    }

    @Override
    public E removeLast() {
        if(!isEmpty()){
            E temp = (E)objects[size - 1];
            size--;
            return temp;
        }
        return null;
    }

    @Override
    public void addFirst(E e) {
        if(size !=  objects.length){
            //size <= i <= 1
            for (int i = size; i > 0; i--) {
                objects[i] = objects[i - 1];
            }
            objects[0] = e;
            size++;
        }
    }

    @Override
    public void addLast(E e) {
        if(size != objects.length){
            objects[size] = e;
            size++;
        }
    }

    @Override
    public boolean contains(E e) {
        for (int i = 0; i < size - 1; i++) {
            if(e != null && e.toString().equals(objects[i].toString())){
                return true;
            }
        }
        return false;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean add(E e) {
        if(size != objects.length){
            objects[size] = e;
            size++;
            return true;
        }
        return false;
    }

    @Override
    public boolean remove(E e) {
        if(!isEmpty()){
            for (int i = 0; i < size; i++) {
                if(e != null && e.toString().equals(objects[i].toString())){
                    //获取了i就是目标元素第一次出现的位置
                    for (int j = i; j < size - 1; j++) {
                        objects[j] = objects[j + 1];
                    }
                    size--;
                    break;
                }
            }
        }
        return false;
    }

    @Override
    public boolean addAll(MyList<E> list) {
        if(size + list.size() <= objects.length){

            for (int i = 0; i < list.size(); i++) {
                objects[size] = list.get(i);
                size++;
            }
        }
        return false;
    }

    @Override
    public boolean addAll(int index, MyList<E> list) {
        if((index >= 0 && index <= size)  && (size + list.size() <= objects.length)){
            for (int i = index; i < size; i++) {
                objects[index + list.size()] = objects[index];
            }
            size+=list.size();
            for (int i = 0; i < list.size(); i++) {
                objects[index + i] = list.get(i);
            }
            return true;
        }

        return false;
    }

    @Override
    public void clear() {
        for (int i = 0; i < size; i++) {
            objects[i] = null;
        }
        size = 0;
    }

    @Override
    public E get(int index) {
        if(0 <= index && index < objects.length){
            return (E)objects[index];
        }
        return null;
    }

    @Override
    public E set(int index, E e) {
        if(index <= 0 && index < size){
            E temp = (E)objects[index];
            objects[index] = e;

            return temp;
        }
        return null;
    }

    @Override
    public void add(int index, E e) {
        if(index >= 0 && size + 1 <= objects.length){
            for (int i = size; i > index; i--) {
                objects[size] = objects[size - 1];
            }
            objects[index] = e;
            size++;
        }
    }

    @Override
    public E remove(int index) {
        if(index <= 0 && index < size){
            for (int i = index; i < size -1; i++) {
                objects[index] = objects[index + 1];
            }
            size--;
        }

        return null;
    }

    @Override
    public int indexOf(E e) {
        for (int i = 0; i < size; i++) {
            if(e != null && e.toString().equals(objects[i].toString())){
                return i;
            }
        }
        return -1;
    }

    @Override
    public int lastIndexOf(E e) {
        for (int i = size - 1; i > 0; i--) {
            if(e != null && e.toString().equals(objects[i].toString())){
                return i;
            }
        }
        return -1;
    }

    @Override
    public MyList<E> getReverseList() {
        MyList<E> temp = new MyArrayList<E>(size);
        for (int i = size - 1; i >= 0; i--) {
            temp.add((E)objects[i]);
        }
        return temp;
    }



    @Override
    public void show(){
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < size; i++) {
            if(i == size - 1){
                sb.append(objects[i]);
            }else {
                sb.append(objects[i].toString() + ",");
            }
        }
        sb.append("]");
        System.out.println(sb.toString());
    }


}
